// 蜂窝蜜造平台生成代码，如手工更改，请添加到 .beeignore 忽略生成

package com.fowo.api.datainterface.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.lang.func.Func1;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.stream.StreamUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.conditions.update.LambdaUpdateChainWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fowo.api.common.query.QueryGenerator;
import com.fowo.api.common.util.ContextHolder;
import com.fowo.api.datainterface.constants.Constants;
import com.fowo.api.datainterface.constants.DatainterfaceTypeKind;
import com.fowo.api.datainterface.constants.MappingColTypeKind;
import com.fowo.api.datainterface.constants.MappingFieldTypeKind;
import com.fowo.api.datainterface.entity.Datainterface;
import com.fowo.api.datainterface.entity.DatainterfaceAuthority;
import com.fowo.api.datainterface.entity.DatainterfaceMapping;
import com.fowo.api.datainterface.entity.DatainterfaceTask;
import com.fowo.api.datainterface.mapper.DatainterfaceTaskMapper;
import com.fowo.api.datainterface.model.DataContextModel;
import com.fowo.api.datainterface.model.DatainterfaceMappingSearchParamPo;
import com.fowo.api.datainterface.model.DatainterfaceTaskSearchParamPo;
import com.fowo.api.datainterface.model.DatainterfaceTaskVo;
import com.fowo.api.datainterface.service.*;
import com.fowo.api.datainterface.util.Common;
import com.fowo.api.datainterface.util.JsonUtil;
import com.fowo.api.datainterface.util.RedisUtil;
import com.fowo.api.sys.model.NewSerialRequest;
import com.fowo.api.sys.service.FileService;
import com.fowo.api.sys.service.SysImportTemplateService;
import com.fowo.api.sys.service.SysSerialService;
import com.fowo.api.user.model.JwtUserInfo;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.hpsf.Decimal;
import org.springframework.beans.BeanUtils;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.stereotype.Service;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.sql.DataSource;
import javax.validation.Validator;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 数据接口事务 服务实现基类
 */
@Service
@Slf4j
@DS("ds21")
public class DatainterfaceTaskServiceImpl
        extends ServiceImpl<DatainterfaceTaskMapper, DatainterfaceTask>
        implements DatainterfaceTaskService {

    public static final Map<String, String> SORT_FIELD_MAP = new HashMap<>();
    // 导出时单次查询最大记录数
    protected static final int EXPORT_QUERY_MAX_SIZE = 1000;
    // 支持导出的最大记录数(1048576 为 Excel 支持的最大行数)
    protected static final long EXPORT_MAX_SIZE = 1048575;

    @Resource
    protected DatainterfaceMappingService datainterfaceMappingService;

    @Resource
    protected FileService fileService;

    @Resource
    protected SysImportTemplateService importTemplateService;

    @Resource
    protected Validator validator;



    @Resource
    private Common common;
    @Resource
    private DatainterfaceAuthorityService datainterfaceAuthorityBaseService;
    @Resource
    private DatainterfaceService datainterfaceService;
    @Resource
    private DataSourceTransactionManager dataSourceTransactionManager;
    @Resource
    private TransactionDefinition transactionDefinition;
    @Resource
    private SysSerialService sysSerialService;

    //@Resource
    //private SQLManager sqlManager;
    private NamedParameterJdbcTemplate jdbcTemplate;

    public NamedParameterJdbcTemplate getJdbcTemplate() {
        if (jdbcTemplate == null) {
            jdbcTemplate = new NamedParameterJdbcTemplate(ContextHolder.getApplicationContext().getBean(DataSource.class));
        }
        return jdbcTemplate;
    }

    @Resource
    private RedisUtil redisUtil;

    /**
     * 测试方法
     */
    @Transactional(rollbackFor = Exception.class)
    public void testTran() {
        datainterfaceService.testTran(1);
        Integer x = 1 / 0;
        datainterfaceService.testTran(1);
    }
    /**
     * 创建数据接口事务
     *
     * @param model 数据接口事务
     * @return 新数据的主键
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public Long create(DatainterfaceTaskVo model) throws Exception {
        JwtUserInfo currentUser = JwtUserInfo.fromHeader();
        DatainterfaceTask entity = new DatainterfaceTask();
        BeanUtils.copyProperties(model, entity);
        entity.setCreateTime(new Date());
        entity.setLastUpdateTime(new Date());
        if (currentUser != null) {
            entity.setCreateUser(currentUser.getUserId());
            entity.setLastUpdateUser(currentUser.getUserId());
        }
        if (this.save(entity)) {
            model.setId(entity.getId());
            updateAllChilds(model);
            return entity.getId();
        }
        throw new Exception("数据接口事务保存失败");
    }

    /**
     * 更新所有子表
     *
     * @param model 数据接口事务
     */
    protected void updateAllChilds(DatainterfaceTaskVo model) throws Exception {
        if (model.getDatainterfaceMappingList() != null) {
            datainterfaceMappingService.saveAllByDatainterfaceTaskTaskMapping(
                    model,
                    model.getDatainterfaceMappingList()
            );
        }
    }

    /**
     * 更新数据接口事务
     *
     * @param model 数据接口事务
     * @return 更新是否成功
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean update(DatainterfaceTaskVo model) throws Exception {
        JwtUserInfo currentUser = JwtUserInfo.fromHeader();
        DatainterfaceTask entity = this.getById(model.getId());
        if (entity == null) {
            throw new Exception("数据接口事务不存在");
        }
        BeanUtils.copyProperties(
                model,
                entity,
                "id",
                "lastUpdateUser",
                "lastUpdateTime",
                "createUser",
                "createTime"
        );
        entity.setLastUpdateTime(new Date());
        if (currentUser != null) {
            entity.setLastUpdateUser(currentUser.getUserId());
        }
        if (this.updateById(entity)) {
            updateAllChilds(model);
            return true;
        }
        return false;
    }

    /**
     * 更新数据接口事务（带空值）
     *
     * @param model 数据接口事务
     * @return 更新是否成功
     */

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateForEdit(DatainterfaceTaskVo model) throws Exception {
        JwtUserInfo currentUser = JwtUserInfo.fromHeader();
        DatainterfaceTask entity = this.getById(model.getId());
        if (entity == null) {
            throw new Exception("数据接口事务不存在");
        }
        model.setLastUpdateTime(new Date());
        if (currentUser != null) {
            model.setLastUpdateUser(currentUser.getUserId());
        }
        boolean isOk = new LambdaUpdateChainWrapper<>(baseMapper)
                .set(DatainterfaceTask::getEnCodeFrom, model.getEnCodeFrom())
                .set(DatainterfaceTask::getCallbackParams, model.getCallbackParams())
                .set(DatainterfaceTask::getDataProcessing, model.getDataProcessing())
                .set(DatainterfaceTask::getDescriptions, model.getDescriptions())
                .set(DatainterfaceTask::getEnabledMark, model.getEnabledMark())
                .set(DatainterfaceTask::getRequestHeaders, model.getRequestHeaders())
                .set(DatainterfaceTask::getRequestParams, model.getRequestParams())
                .set(DatainterfaceTask::getSysariables, model.getSysariables())
                .set(DatainterfaceTask::getEnCodeTo, model.getEnCodeTo())
                .set(DatainterfaceTask::getTaskName, model.getTaskName())
                .set(DatainterfaceTask::getTaskCode, model.getTaskCode())
                .set(DatainterfaceTask::getLastUpdateUser, model.getLastUpdateUser())
                .set(DatainterfaceTask::getLastUpdateTime, model.getLastUpdateTime())
                .eq(DatainterfaceTask::getId, model.getId())
                .update();
        if (isOk) {
            updateAllChilds(model);
        }
        return isOk;
    }

    /**
     * 删除数据接口事务
     *
     * @param id 数据接口事务的主键
     * @return 删除是否成功
     */
    @Override
    public boolean delete(Long id) throws Exception {
        return this.removeById(id);
    }

    /**
     * 批量删除数据接口事务
     *
     * @param ids 数据接口事务的主键列表
     * @return 删除是否成功
     */
    @Override
    public boolean batchDelete(List<Long> ids) throws Exception {
        return baseMapper.deleteBatchIds(ids) > 0;
    }


    /**
     * 通过源接口编码查询数据接口事务主键(重复时返回最新的主键)
     */
    @Override
    public Long getIdByEnCodeFrom(String enCodeFrom) {
        return this.getObj(Wrappers.<DatainterfaceTask>lambdaQuery().select(DatainterfaceTask::getId).eq(DatainterfaceTask::getEnCodeFrom, enCodeFrom), res -> Convert.toLong(res));
    }

    /**
     * 通过源接口编码查询数据接口事务多主键(重复时返回最新的主键)
     */
    @Override
    public List<Long> getIdsByEnCodeFrom(List<String> list) {
        return this.listObjs(Wrappers.<DatainterfaceTask>lambdaQuery().select(DatainterfaceTask::getId).in(DatainterfaceTask::getEnCodeFrom, list), res -> Convert.toLong(res));
    }

    /**
     * 通过数据接口事务主键查询源接口编码
     */
    @Override
    public String getEnCodeFromById(Long id) {
        return this.getObj(Wrappers.<DatainterfaceTask>lambdaQuery().select(DatainterfaceTask::getEnCodeFrom).eq(DatainterfaceTask::getId, id), res -> Convert.toStr(res));
    }

    /**
     * 通过数据接口事务主键查询源接口编码列表
     */
    @Override
    public List<String> getEnCodeFromByIds(List<Long> ids) {
        return this.listObjs(Wrappers.<DatainterfaceTask>lambdaQuery().select(DatainterfaceTask::getEnCodeFrom).in(DatainterfaceTask::getId, ids), res -> Convert.toStr(res));
    }

    /**
     * 获取详情
     *
     * @param id 数据接口事务的主键
     */
    @Override
    public DatainterfaceTaskVo getVoById(Long id) throws Exception {
        DatainterfaceTask vo = this.getById(id);
        if (vo == null) {
            return null;
        }
        DatainterfaceTaskVo taskVo = BeanUtil.copyProperties(vo, DatainterfaceTaskVo.class);
        DatainterfaceMappingSearchParamPo taskMappingSearchParamPo = new DatainterfaceMappingSearchParamPo();
        taskMappingSearchParamPo.setTaskCode(vo.getTaskCode());
        taskVo.setDatainterfaceMappingList(datainterfaceMappingService.search(taskMappingSearchParamPo));

        return taskVo;
    }

    /**
     * 分页查询数据接口事务
     *
     * @param search 查询条件
     * @return 数据接口事务分页查询结果
     */
    @Override
    public Page<DatainterfaceTask> pageSearch(
            DatainterfaceTaskSearchParamPo search
    ) {
        DatainterfaceTask DatainterfaceTask = BeanUtil.copyProperties(search, DatainterfaceTask.class);
        QueryWrapper<DatainterfaceTask> queryWrapper = QueryGenerator.initQueryWrapper(DatainterfaceTask, search);
        Page<DatainterfaceTask> pageList = this.page(search.toPage(), queryWrapper);
        return pageList;
    }

    /**
     * 列表查询数据接口事务
     *
     * @param search 查询条件
     * @return 数据接口事务列表查询结果
     */
    @Override
    public List<DatainterfaceTask> search(
            DatainterfaceTaskSearchParamPo search
    ) {
        DatainterfaceTask DatainterfaceTask = BeanUtil.copyProperties(search, DatainterfaceTask.class);
        QueryWrapper<DatainterfaceTask> queryWrapper = QueryGenerator.initQueryWrapper(DatainterfaceTask, search);
        return this.list(queryWrapper);
    }

    /**
     * 查询数据接口事务最后更新时间
     *
     * @param search 查询条件
     * @return 数据接口事务最后更新时间
     */
    @Override
    public Date searchLastUpdateTime(DatainterfaceTaskSearchParamPo search) {
        DatainterfaceTask DatainterfaceTask = BeanUtil.copyProperties(search, DatainterfaceTask.class);
        QueryWrapper<DatainterfaceTask> queryWrapper = QueryGenerator.initQueryWrapper(DatainterfaceTask, search, null, null);
        queryWrapper.select("max(last_update_time) last_update_time");
        return this.getObj(queryWrapper, res -> Convert.toDate(res));
    }





    /**
     * 拷贝
     *
     * @param id
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean copy(Long id) {
        DatainterfaceTask entity = this.getById(id);
        List<DatainterfaceMapping> list = datainterfaceMappingService.list(Wrappers.<DatainterfaceMapping>lambdaQuery().eq(DatainterfaceMapping::getTaskCode, entity.getTaskCode()));
        String number = sysSerialService.getNewSerial(new NewSerialRequest(null, "DatainterfaceTask.taskCode"));
        entity.setTaskCode(number);
        entity.setTaskName(entity.getTaskName() + ".副本" + RandomUtil.randomNumbers(5));
        DatainterfaceTask entity1 = BeanUtil.copyProperties(entity, DatainterfaceTask.class, "id");
        List<DatainterfaceMapping> list1 = CollUtil.newArrayList();
        for (DatainterfaceMapping item : list) {
            item.setTaskCode(entity.getTaskCode());
            DatainterfaceMapping datainterfaceMapping = BeanUtil.copyProperties(item, DatainterfaceMapping.class, "id");
            list1.add(datainterfaceMapping);
        }
        if (this.save(entity1)) {
            return datainterfaceMappingService.saveBatch(list1);
        }
        return false;
    }

    /**
     * 根据Task组装上下文&发送请求
     *
     * @param contextModel     事务上下文
     * @param dataTaskTypeKind 请求或发送：DatainterfaceTypeKind
     * @return
     */
    @Override
    public DataContextModel getToInfoByTaskCode(DataContextModel contextModel, String dataTaskTypeKind, Func1<DataContextModel.DatainterfaceToModel, JSONObject> funcParams,
                                                Func1<DataContextModel.DatainterfaceToModel, JSONObject> funcHeaders) {

        if (StrUtil.equalsIgnoreCase(DatainterfaceTypeKind.From.getValue(), dataTaskTypeKind)) {
            Assert.isTrue(ObjectUtil.isAllNotEmpty(contextModel, contextModel.getTaskCode()), "未找到事务信息，请检查");
            DatainterfaceTask entity = this.getOne(Wrappers.<DatainterfaceTask>lambdaQuery()
                    .eq(DatainterfaceTask::getTaskCode, contextModel.getTaskCode()), false);
            Assert.isTrue(ObjectUtil.isNotEmpty(entity), "事务编号 {} 不存在，请检查", StrUtil.toStringOrNull(contextModel.getId()));
            List<DatainterfaceMapping> mappingList = datainterfaceMappingService.list(Wrappers.<DatainterfaceMapping>lambdaQuery()
                    .eq(DatainterfaceMapping::getTaskCode, entity.getTaskCode()));
            if (CollUtil.isNotEmpty(mappingList)) {
                contextModel.setMapping(StreamUtil.of(mappingList).map(m -> BeanUtil.copyProperties(m, new DataContextModel().new DatainterfaceMappingModel().getClass()))
                        .collect(Collectors.toList()));
            }
            BeanUtil.copyProperties(entity, contextModel);
            //Assert.isTrue(ObjectUtil.isAllNotEmpty(  entity.getEnCodeTo(), entity.getAppCodeFrom(), entity.getEnCodeFrom()), "事务:{} 未配置来源或目标接口信息，请检查", entity.getTaskCode());
            Assert.isTrue(ObjectUtil.isAllNotEmpty(entity.getEnCodeTo(), entity.getEnCodeFrom()), "事务:{} 未配置来源或目标接口信息，请检查", entity.getTaskCode());
            this.initDatainterfaceList(contextModel, dataTaskTypeKind);
            callContextFromDefault(contextModel);
        } else if (StrUtil.equalsIgnoreCase(DatainterfaceTypeKind.To.getValue(), dataTaskTypeKind)) {
            this.initDatainterfaceList(contextModel, dataTaskTypeKind);
            callContextToDefault(contextModel, funcParams, funcHeaders);
        }
        return contextModel;
    }


    /**
     * 接口以及接口信息赋值
     */
    @Override
    public void initDatainterfaceList(DataContextModel context, String dataTaskTypeKind) {
        Assert.isTrue(ObjectUtil.isNotEmpty(context), "未找到事务信息，请检查");
        if (StrUtil.equalsIgnoreCase(DatainterfaceTypeKind.From.getValue(), dataTaskTypeKind)) {
            List<DataContextModel.DatainterfaceFromModel> datainterfaceList = new ArrayList<>();
            String enCode = context.getEnCodeFrom();
            Assert.isTrue(StrUtil.isNotBlank(enCode), "事务 {} 来源接口未配置", context.getTaskCode());
            List<Datainterface> interfaceListForm = datainterfaceService.list(Wrappers.<Datainterface>lambdaQuery()
                    .in(StrUtil.isNotEmpty(enCode), Datainterface::getEnCode, StrUtil.split(enCode, ",")));
            List<DataContextModel.DatainterfaceMappingModel> mappingList = context.getMapping();
            Assert.isTrue(CollUtil.isNotEmpty(interfaceListForm), "事务 {} 来源接口数据信息不存在", context.getTaskCode());
            //多个来源
            for (Datainterface t : interfaceListForm) {
                DatainterfaceAuthority entityAuthority = datainterfaceAuthorityBaseService.getOne(Wrappers.<DatainterfaceAuthority>lambdaQuery().eq(DatainterfaceAuthority::getAppCode, t.getAppCode()), false);
                Assert.isTrue(ObjectUtil.isNotEmpty(entityAuthority), "事务 {} 目标接口 {} 授权数据信息不存在，请检查配置", context.getTaskCode(), enCode);
                DataContextModel.DatainterfaceFromModel datainterfaceModel = BeanUtil.copyProperties(t, context.new DatainterfaceFromModel().getClass());
                datainterfaceModel.setAuthority(BeanUtil.copyProperties(entityAuthority, new DataContextModel().new DatainterfaceAuthorityModel().getClass()));
                datainterfaceModel.setTaskCode(context.getTaskCode());
                //赋默认值
                if (StrUtil.isNotBlank(context.getRequestParams())) {
                    datainterfaceModel.setRequestParams(context.getRequestParams());
                }
                if (StrUtil.isNotBlank(context.getRequestHeaders())) {
                    datainterfaceModel.setRequestHeaders(context.getRequestHeaders());
                }
                //设置来源mapping(一个或多个from  一个to)
                Collection<DataContextModel.DatainterfaceMappingModel> currentMapping = CollUtil.filterNew(mappingList, f -> StrUtil.equals(f.getEnCodeFrom(), t.getEnCode()));
                if (CollUtil.isNotEmpty(currentMapping)) {
                    datainterfaceModel.setMapping(StreamUtil.of(currentMapping).map(m -> BeanUtil.copyProperties(m, context.new DatainterfaceMappingModel().getClass())).collect(Collectors.toList()));
                }
                datainterfaceList.add(datainterfaceModel);
            }
            context.setFrom(datainterfaceList);
        } else if (StrUtil.equalsIgnoreCase(DatainterfaceTypeKind.To.getValue(), dataTaskTypeKind)) {
            List<DataContextModel.DatainterfaceToModel> datainterfaceList = new ArrayList<>();
            String enCode = context.getEnCodeTo();
            Assert.isTrue(StrUtil.isNotBlank(enCode), "事务 {} 目标接口未配置", context.getTaskCode());
            //多个目标
            List<Datainterface> interfaceListTo = datainterfaceService.list(Wrappers.<Datainterface>lambdaQuery()
                    .in(StrUtil.isNotEmpty(enCode), Datainterface::getEnCode, StrUtil.split(enCode, ",")));
            List<DataContextModel.DatainterfaceMappingModel> mappingList = context.getMapping();
            Assert.isTrue(CollUtil.isNotEmpty(interfaceListTo), "事务 {} 目标接口数据信息不存在", context.getTaskCode());
            for (Datainterface t : interfaceListTo) {
                DatainterfaceAuthority entityAuthority = datainterfaceAuthorityBaseService.getOne(Wrappers.<DatainterfaceAuthority>lambdaQuery().eq(DatainterfaceAuthority::getAppCode, t.getAppCode()), false);
                Assert.isTrue(ObjectUtil.isNotEmpty(entityAuthority), "事务 {} 目标接口 {} 授权数据信息不存在，请检查配置", context.getTaskCode(), t.getEnCode());
                DataContextModel.DatainterfaceToModel datainterfaceModel = BeanUtil.copyProperties(t, context.new DatainterfaceToModel().getClass());
                datainterfaceModel.setAuthority(BeanUtil.copyProperties(entityAuthority, new DataContextModel().new DatainterfaceAuthorityModel().getClass()));
                datainterfaceModel.setTaskCode(context.getTaskCode());

                //设置目标mapping(一个from  一个或多个 to)
                Collection<DataContextModel.DatainterfaceMappingModel> currentMapping = CollUtil.filterNew(mappingList, f -> StrUtil.equals(f.getEnCodeTo(), t.getEnCode()));
                if (CollUtil.isNotEmpty(currentMapping)) {
                    datainterfaceModel.setMapping(StreamUtil.of(currentMapping).map(m -> BeanUtil.copyProperties(m, context.new DatainterfaceMappingModel().getClass())).collect(Collectors.toList()));
                }
                //未指定环境，默认为正式环境
                if (StrUtil.isBlank(datainterfaceModel.getEnvironment())) {
                    datainterfaceModel.setEnvironment(Constants.Produce);
                }
                datainterfaceList.add(datainterfaceModel);
            }
            context.setTo(datainterfaceList);
        }
    }

    /**
     * 处理From
     *
     * @param context
     * @func 在from后mapping前
     */
    public void callContextFromDefault(DataContextModel context) {
        //多个来源
        context.getFrom().forEach(datainterfaceModel -> {
            JSONObject currentParamsMap = common.convertCurrentMap(null, JsonUtil.getJsonToList(datainterfaceModel.getRequestParams()));
            JSONObject currentHeadersMap = common.convertCurrentMap(null, JsonUtil.getJsonToList(datainterfaceModel.getRequestHeaders()));
            Object infoById = datainterfaceService.executeInterfaceByContextFrom(datainterfaceModel, currentParamsMap, currentHeadersMap);
            datainterfaceModel.setData(infoById);
        });
    }

    /**
     * 处理只有一个To的映射
     *
     * @param context
     * @func 在mapping后to前
     */
    public void callContextToDefault(DataContextModel context, Func1<DataContextModel.DatainterfaceToModel, JSONObject> funcParams, Func1<DataContextModel.DatainterfaceToModel, JSONObject> funcHeaders) {
        Assert.isTrue(ObjectUtil.isNotEmpty(context), "未找到事务信息，请检查");
        Assert.isTrue(CollUtil.isNotEmpty(context.getFrom()) && CollUtil.isNotEmpty(context.getTo()), "事务 {} 来源或目标接口信息不存在", context.getTaskCode());
        //一个来源 、一个、多个目标
        if (CollUtil.size(context.getTo()) > 0 && CollUtil.size(context.getFrom()) == 1) {
            DataContextModel.DatainterfaceFromModel interfaceFrom = CollUtil.getFirst(context.getFrom());
            List<DataContextModel.DatainterfaceToModel> interfaceToList = context.getTo();
            //开启事务
            TransactionStatus txs = null;
            try {
                txs = dataSourceTransactionManager.getTransaction(transactionDefinition);
                //校验
                for (DataContextModel.DatainterfaceToModel interfaceTo : interfaceToList) {
                    JSONObject currentParamsMap = common.convertCurrentMap(null, JsonUtil.getJsonToList(interfaceTo.getRequestParams()));
                    JSONObject currentHeadersMap = common.convertCurrentMap(null, JsonUtil.getJsonToList(interfaceTo.getRequestHeaders()));
                    List<JSONObject> dataList = convertResult(context, interfaceFrom, interfaceTo);
                    Assert.isTrue(CollUtil.isNotEmpty(dataList), "事务 {} 转换来源接口 {} 数据错误 ,错误信息 {} ", context.getTaskCode(), interfaceFrom.getEnCode(), StrUtil.subPre(JsonUtil.getObjectToString(interfaceFrom.getData()), 500));
                    checkMappingInfoFrom(interfaceTo, interfaceTo.getMapping(), dataList);
                    JSONArray data = MapUtil.get(interfaceTo.getMappingSuccessData(), interfaceTo.getEnCode(), JSONArray.class);
                    Assert.isTrue(CollUtil.isNotEmpty(data), "事务 {} 转换为目标接口 {} 数据为空  转换的数据 {}", context.getTaskCode(), interfaceTo.getEnCode(), StrUtil.subPre(JsonUtil.getObjectToString(interfaceTo.getMappingSuccessData()), 500));
                    //钩子处理参数
                    try {
                        if (ObjectUtil.isNotEmpty(funcParams)) {
                            currentParamsMap = funcParams.callWithRuntimeException(interfaceTo);
                        }
                        //钩子处理请求头
                        if (ObjectUtil.isNotEmpty(funcHeaders)) {
                            currentHeadersMap = funcHeaders.callWithRuntimeException(interfaceTo);
                        }
                    } catch (Exception ex) {
                        throw new RuntimeException(StrUtil.format("事务 {} 执行用户自定义逻辑发生异常 ", context.getTaskCode()), ex);
                    }
                    datainterfaceService.executeInterfaceByContextTo(interfaceTo, currentParamsMap, currentHeadersMap);
                    interfaceTo.setMappingSuccessData(null);
                    interfaceTo.setMapping(null);
                    interfaceTo.setAuthority(null);
                }
                // 提交事务
                dataSourceTransactionManager.commit(txs);
            } catch (Exception e) {
                if (ObjectUtil.isNotEmpty(txs)) {
                    dataSourceTransactionManager.rollback(txs);
                }
                throw e;
            }
            interfaceFrom.setData(null);
        } else {
            Assert.isTrue(false, "事务 {} 系统暂不支持的配置组合", context.getTaskCode());
        }
    }

    /**
     * 来源结果转换为目标
     *
     * @param context
     * @param interfaceFrom
     * @param interfaceTo
     * @return
     */
    private static List<JSONObject> convertResult(DataContextModel context, DataContextModel.DatainterfaceFromModel interfaceFrom, DataContextModel.DatainterfaceToModel interfaceTo) {
        //把数据转回返回结果
        List<JSONObject> dataList = null;
        try {
            dataList = JsonUtil.getJsonToList(JsonUtil.getJsonToJsonArray(JSON.toJSONString(interfaceFrom.getData(), SerializerFeature.WriteMapNullValue)));
        } catch (Exception e) {
            try {
                JSONObject obj = JsonUtil.getJsonToBean(interfaceFrom.getData(), JSONObject.class);
                dataList = JsonUtil.getJsonToList(JSON.toJSONString(MapUtil.get(obj, interfaceTo.getEnCode(), Object.class, null), SerializerFeature.WriteMapNullValue));
                if (CollUtil.isEmpty(dataList)) {
                    dataList = CollUtil.newArrayList(obj);
                }
            } catch (Exception eee) {
                Assert.isTrue(false, "事务 {} 转换来源接口 {} 数据错误 ,错误信息 {} ", context.getTaskCode(), interfaceFrom.getEnCode(), StrUtil.subPre(JsonUtil.getObjectToString(interfaceFrom.getData()), 500));
            }
        }
        return dataList;
    }


    /**
     * 根据来源接口mapping&data逐一校验
     *
     * @param to
     * @param mappingList
     * @param dataList
     * @return
     */
    private void checkMappingInfoFrom(DataContextModel.DatainterfaceToModel to, List<DataContextModel.DatainterfaceMappingModel> mappingList, List<JSONObject> dataList) {
        if (CollUtil.isEmpty(dataList)) {
            return;
        }
        //未设置映射，默认自定义转换
        if (CollUtil.isEmpty(mappingList)) {
            to.setMappingSuccessData(MapUtil.of(to.getEnCode(), dataList));
            return;
        }
        List<JSONObject> successDataList = CollUtil.newArrayList();
        List<JSONObject> failDataList = CollUtil.newArrayList();
        //循环来源返回的结果
        for (JSONObject data : dataList) {
            JSONObject successData = new JSONObject();
            JSONObject failData = new JSONObject();
            StringBuilder message = new StringBuilder();
            String pkValue = StrUtil.EMPTY;
            String fieldFrom = StrUtil.EMPTY;
            try {
                if (StrUtil.isNotEmpty(message.toString())) {
                    break;
                }
                DataContextModel.DatainterfaceMappingModel primaryKey = CollUtil.findOne(mappingList, f -> StrUtil.equals(Constants.TrueKind, StrUtil.toStringOrNull(f.getPrimaryKeyTo())));
                if (ObjectUtil.isNotEmpty(primaryKey)) {
                    pkValue = MapUtil.getStr(data, primaryKey.getFieldFrom(), JsonUtil.getObjectToString(data));
                }
                for (DataContextModel.DatainterfaceMappingModel currentMapping : mappingList) {
                    fieldFrom = currentMapping.getFieldFrom();
                    String value = MapUtil.getStr(data, fieldFrom);
                    //配置字段处理
                    if (StrUtil.isEmpty(message.toString())) {
                        value = StrUtil.toStringOrNull(convertMappingColType(data, currentMapping, value));
                    }
                    //主键非空验证
                    if (StrUtil.isEmpty(message.toString())) {
                        if (StrUtil.equals(Constants.TrueKind, StrUtil.toStringOrNull(currentMapping.getAllowNullFrom()))) {
                            if (StrUtil.isEmpty(value)) {
                                message.append(StrUtil.format("数据:{} :字段：{} 不能为空", pkValue, currentMapping.getFieldFrom()));
                            }
                        }
                    }
                    //非空验证
                    if (StrUtil.isEmpty(message.toString())) {
                        if (StrUtil.equals(Constants.TrueKind, StrUtil.toStringOrNull(currentMapping.getPrimaryKeyTo()))) {
                            if (StrUtil.isEmpty(value)) {
                                message.append(StrUtil.format("数据:{} :字段：{} 不能为空", pkValue, currentMapping.getFieldFrom()));
                            }
                        }
                    }
                    //长度验证
                    if (StrUtil.isEmpty(message.toString())) {
                        if (ObjectUtil.isNotEmpty(currentMapping.getDataLengthFrom()) && NumberUtil.compare(StrUtil.length(value), currentMapping.getDataLengthFrom()) > 0) {
                            message.append(StrUtil.format("数据:{} :字段：{} 超过映射设置长度", pkValue, currentMapping.getFieldFrom()));
                        }
                    }
                    //类型验证&转换
                    if (StrUtil.isEmpty(message.toString())) {
                        message.append(convertMappingSuccessData(successData, pkValue, currentMapping, value));
                    }
                }

            } catch (Exception ex) {
                if (StrUtil.isEmpty(message.toString())) {
                    message.append(StrUtil.format("数据:{} :字段：{} :转换映射 {} 错误信息：{}", data, pkValue, fieldFrom, ex.getMessage()));
                }
            } finally {
                if (StrUtil.isEmpty(message.toString())) {
                    successDataList.add(successData);
                } else {
                    failData.put(message.toString(), data);
                    failDataList.add(failData);
                }
            }
        }
        //一个to接口出现多个映射结果直接union
        common.packSuccessData(to, successDataList);
        common.packFailData(to, failDataList);

    }


    /**
     * 配置字段处理：字段描述、列类型、源表、源字段、目标表、目标字段、备注
     * 列类型：字段列、固定值、自动列、表达式、其他（分组列、求和列、平均列、最大值、最小值、计算列）--单选
     * 固定列（Fixed）：可设置固定值，如：1、2
     * 自动列（Auto）：自动获值的列，比如单据号/ID字段
     * 表达式（Expression）：支持预设的类型，比如当前日期/当前用户/当前会计期
     * 固定替换列（ReplaceFixed）： 采用逗号（不考虑默认值是,）分隔替换
     * 自定义脚本（Sql）： 根据当前值查询对应结果,来源数据无数据：sql无参数
     */
    private Object convertMappingColType(JSONObject currentData, DataContextModel.DatainterfaceMappingModel currentMapping, String value) {
        String colSysariables = currentMapping.getColSysariables();
        if (StrUtil.isNotEmpty(colSysariables)) {
            if (StrUtil.equals(MappingColTypeKind.Fixed.getValue(), StrUtil.toStringOrNull(currentMapping.getColType()))) {
                return StrUtil.nullToDefault(colSysariables, value);
            } else if (StrUtil.equals(MappingColTypeKind.Auto.getValue(), StrUtil.toStringOrNull(currentMapping.getColType()))) {
                return MapUtil.getStr(currentData, colSysariables, value);
            } else if (StrUtil.equals(MappingColTypeKind.Expression.getValue(), StrUtil.toStringOrNull(currentMapping.getColType()))) {
                return common.convertColSysariables(value, colSysariables);
            } else if (StrUtil.equals(MappingColTypeKind.ReplaceFixed.getValue(), StrUtil.toStringOrNull(currentMapping.getColType()))) {
                for (String item : StrUtil.split(colSysariables, ",")) {
                    value = StrUtil.removeAll(value, item);
                }
                return value;
            } else if (StrUtil.equals(MappingColTypeKind.Sql.getValue(), StrUtil.toStringOrNull(currentMapping.getColType()))) {
                return common.executeSql(colSysariables, value, MappingFieldTypeKind.String.getValue());
            }
        }
        return value;
    }


    /**
     * 类型转换&成功赋值
     *
     * @param successData
     * @param primaryKeyValue
     * @param currentMapping
     * @param value
     */
    private static String convertMappingSuccessData(JSONObject successData, String primaryKeyValue, DataContextModel.DatainterfaceMappingModel currentMapping, String value) {
        StringBuilder resMessage = new StringBuilder();
        if (StrUtil.isEmpty(value)) {
            successData.put(currentMapping.getFieldTo(), null);
        } else {
            // 判断是整形
            if (StrUtil.equalsIgnoreCase(MappingFieldTypeKind.Int.getValue(), currentMapping.getDataTypeFrom())) {
                try {
                    successData.put(currentMapping.getFieldTo(), Integer.parseInt(value));
                } catch (Exception e) {
                    resMessage.append(StrUtil.format("数据:{} :字段：{} 映射类型必须为整型", primaryKeyValue, currentMapping.getFieldFrom()));
                }
            }
            if (StrUtil.equalsIgnoreCase(MappingFieldTypeKind.Long.getValue(), currentMapping.getDataTypeFrom())) {
                try {
                    successData.put(currentMapping.getFieldTo(), Convert.convert(Long.class, value));
                } catch (Exception e) {
                    resMessage.append(StrUtil.format("数据:{} :字段：{} 映射类型必须为长整型", primaryKeyValue, currentMapping.getFieldFrom()));
                }
            }
            if (StrUtil.equalsIgnoreCase(MappingFieldTypeKind.Bool.getValue(), currentMapping.getDataTypeFrom())) {
                try {
                    successData.put(currentMapping.getFieldTo(), Convert.convert(Boolean.class, value));
                } catch (Exception e) {
                    resMessage.append(StrUtil.format("数据:{} :字段：{} 映射类型必须为布尔型", primaryKeyValue, currentMapping.getFieldFrom()));
                }
            } else if (StrUtil.equalsIgnoreCase(MappingFieldTypeKind.Decimal.getValue(), currentMapping.getDataTypeFrom())) {
                try {
                    successData.put(currentMapping.getFieldTo(), Convert.convert(Decimal.class, value));
                } catch (Exception e) {
                    resMessage.append(StrUtil.format("数据:{} :字段：{} 映射类型必须为高精度小数型", primaryKeyValue, currentMapping.getFieldFrom()));
                }
            } else if (StrUtil.equalsIgnoreCase(MappingFieldTypeKind.Float.getValue(), currentMapping.getDataTypeFrom())) {
                try {
                    successData.put(currentMapping.getFieldTo(), Convert.convert(Float.class, value));
                } catch (Exception e) {
                    resMessage.append(StrUtil.format("数据:{} :字段：{} 映射类型必须为单精度浮点型", primaryKeyValue, currentMapping.getFieldFrom()));
                }
            } else if (StrUtil.equalsIgnoreCase(MappingFieldTypeKind.Double.getValue(), currentMapping.getDataTypeFrom())) {
                try {
                    successData.put(currentMapping.getFieldTo(), Double.valueOf(value));
                } catch (Exception e) {
                    resMessage.append(StrUtil.format("数据:{} :字段：{} 映射类型必须为双精度浮点型", primaryKeyValue, currentMapping.getFieldFrom()));
                }
            } else if (StrUtil.equalsIgnoreCase(MappingFieldTypeKind.Datetime.getValue(), currentMapping.getDataTypeFrom())) {
                try {
                    SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                    successData.put(currentMapping.getFieldTo(), formatter.parse(value));
                } catch (Exception e) {
                    resMessage.append(StrUtil.format("数据:{} :字段：{} 映射类型必须为日期时间型", primaryKeyValue, currentMapping.getFieldFrom()));
                }
            } else {
                try {
                    successData.put(currentMapping.getFieldTo(), StrUtil.toStringOrNull(value));
                } catch (Exception e) {
                    resMessage.append(StrUtil.format("数据:{} :字段：{} 映射类型必须为字符串类型", primaryKeyValue, currentMapping.getFieldFrom()));
                }
            }
        }
        return resMessage.toString();
    }
}
